﻿using CoachingOrganizer.Logic.Helpers;
using CoachingOrganizer.Logic.Logic.Tools.MoodLevel;
using CoachingOrganizer.Toolkit.Events;
using CoachingOrganizer.Toolkit.Threading.CollectionsDecorators;
using System;
using System.Collections.Generic;
using System.Collections.Specialized;
using System.Linq;
using System.Text;
using System.Threading.Tasks;

namespace CoachingOrganizer.Logic.Models.Tools.MoodLevel
{
    public class MoodLevelModel : ToolModelBase
    {
        private readonly SimpleCollectionLoadDecorator<MoodValueModel> _values;
        private MoodDayCacheModel[] _days;
        private MoodDayCacheModel _selectedDay;
        private DateTime _startDate = DateTime.Today;
        private DateTime _finishDate = DateTime.Today.AddDays(7.0);
        private TimeSpan _period = TimeSpan.FromHours(1.0);

        public DateTime StartDate
        {
            get { return _startDate; }
            set { _startDate = value; }
        }

        public DateTime FinishDate
        {
            get { return _finishDate; }
            set { _finishDate = value; }
        }

        public TimeSpan Period
        {
            get { return _period; }
            set { _period = value; }
        }

        public MoodDayCacheModel[] Days
        {
            get { return _days; }
            internal set { _days = value; }
        }

        public MoodDayCacheModel SelectedDay
        {
            get { return _selectedDay; }
            set
            {
                _selectedDay = value;
                OnSelectedDayChanged();
            }
        }

        public IEnumerable<MoodValueModel> Values
        {
            get { return _values.Items; }
        }

        public event EventHandler ValuesChanged
        {
            add { _values.ItemsChanged += value; }
            remove { _values.ItemsChanged -= value; }
        }

        public event NotifyCollectionChangedEventHandler ValuesCollectionChanged
        {
            add { _values.ItemsCollectionChanged += value; }
            remove { _values.ItemsCollectionChanged -= value; }
        }

        public event EventHandler SelectedDayChanged;

        internal Func<DateTime, IEnumerable<MoodValueModel>> EnumerateDayValuesDelegate;

        internal Func<ActionResult<IEnumerable<MoodValueLogic>>> EnumerateMoodValuesDelegate;

        internal Action UpdateDaysDelegate;

        public MoodLevelModel()
        {
            _values = new SimpleCollectionLoadDecorator<MoodValueModel>(EnumerateMoodValues);
        }

        public async Task LoadMoodValuesAsync(System.Threading.CancellationToken cancelLoad)
        {
            await Task.Run(() => _values.FillItemsList(), cancelLoad);
            UpdateDaysDelegate();
        }

        public IEnumerable<MoodValueModel> EnumerateDayValues(DateTime day)
        {
            return EnumerateDayValuesDelegate(day);
        }

        internal void AddValue(MoodValueModel moodValue)
        {
            _values.ModifyCollection(col => col.Add(moodValue));
        }

        private ActionResult<IEnumerable<MoodValueModel>> EnumerateMoodValues()
        {
            return UpdateHelper.EnumerateModels(EnumerateMoodValuesDelegate, l => l.Model);
        }

        protected virtual void OnSelectedDayChanged()
        {
            EventHandler handler = SelectedDayChanged;
            if (handler != null)
                handler(this, EventArgs.Empty);
        }

    }
}
